import baseFunc from '../baseFunc';

const constant = 57.29577951308232;
const dataJson = {
	checkedMap: [],
	checkedSheetMap: [],
	currentPageData: [],
	cancelTokenObj: {},
	multiTargetId: [],
};

const dataSources = {
	cundang: new Cesium.CustomDataSource('cundang'),
	dingzhi: new Cesium.CustomDataSource('dingzhi'),
	promote: new Cesium.CustomDataSource('promote'),
	historyPathMarker: new Cesium.CustomDataSource('historyPathMarker'),
	monitorScenePrimitives: new Cesium.PrimitiveCollection(),
};
const ClusteringDataSources = {};
const imgEnum = {
	defaultImg:
		'',
	radar: require('@/assets/images/buoy/leida.png'),
	fj: require('@/assets/images/buoy/fengji.png'),
	fjR: require('@/assets/images/buoy/fengjiR.png'),
	hy: require('@/assets/images/buoy/buoyB.png'),
	760: require('@/assets/images/buoy/buoyB.png'),
	fc: require('@/assets/images/buoy/fengchang.png'),
	video: require('@/assets/images/buoy/shipin.png'),
};
const degreesToRadian = Math.PI / 180;

// 存储监听事见
let listenerArr = [];
// 存储倾斜摄影对象
let dsm = null;

// 复杂多面栅格化使用
/**
 * 平移点位置
 * @param {Array}   position    目标点坐标,[lon, lat]
 * @param {Array}   duration    方向坐标
 * @param {Number}  distance    距离
 */
function translationPoint(position, duration, distance) {
	let p = new Cesium.Cartographic(Cesium.Math.toRadians(position[0]), Cesium.Math.toRadians(position[1]), 0);
	let d = new Cesium.Cartographic(Cesium.Math.toRadians(position[0] + duration[0]), Cesium.Math.toRadians(position[1] + duration[1]), 0);
	return new Cesium.EllipsoidGeodesic(p, d).interpolateUsingSurfaceDistance(distance);
}

/**
 * 将wkt格式数据转化为经纬度
 * @param {String} wktString wkt格式点坐标
 */
function wktToDegrees(wktString) {
	let str = wktString.replace(/[POLYGONpolygon()]/g, '');
	str = str.replace(/,/g, ' ');
	return str
		.split(' ')
		.map(parseFloat)
		.filter(item => item || item === 0);
}
/**
 * 将wkt格式数据转化为笛卡尔坐标
 * @param {String} wktString wkt格式点坐标
 */
function wktToCartesian3(wktString) {
	return Cesium.Cartesian3.fromDegreesArray(wktToDegrees(wktString));
}
/**
 * 更新目标坐标位置
 * @param {Array}   positions   更新的坐标数组
 * @param {Object}  center      包围球圆心
 * @param {Number}  radius      包围球半径
 */
function updateTargetPositions(positions, center, radius) {
	positions.push(positions[0]);
	let entity = viewer.entities.getById('target');
	if (entity && entity.polyline.positions.length > 0) {
		entity.position = center;
		entity.polyline.positions = positions;
	} else {
		func.createTarget(center, positions, radius);
	}
}

function coordinateHandle(coords, positions) {
	let result = 0;
	let isNegative = /[WwSs-]/g.test(coords);
	coords = coords.replace(/[EeWwSsNn-]/, '');
	if (/['"]/g.test(coords) && !/[°]/g.test(coords)) {
		if (!/[']/g.test(coords)) {
			let strCoords = coords.split(/["]/g);
			positions[positions.length - 1] += Number(strCoords[0]) / 3600;
		} else {
			let strCoords = coords.split(/['"]/g);
			positions[positions.length - 1] += Number(strCoords[0]) / 60;
			strCoords[1] && (positions[positions.length - 1] += Number(strCoords[1]) / 3600);
		}
		return;
	} else {
		let strCoords = coords.split(/[°'":]/g);
		result += Number(strCoords[0]);
		strCoords[1] && (result += Number(strCoords[1]) / 60);
		strCoords[2] && (result += Number(strCoords[2]) / 3600);
	}
	result = isNegative ? -result : result;
	if (positions) {
		positions.push(result);
		return positions;
	} else {
		return result;
	}
}

const func = {
	/**
	 * 点目标处理   ps:暂时弃用
	 * @param {String}  point   目标点，wkt格式
	 */
	addTarget(point) {
		this.clearToolArea();
		if (!point) return;
		point = point.replace('POINT (', '').replace(')', '').split(' ');

		let position = Cesium.Cartesian3.fromDegrees(Number(point[0]), Number(point[1]));
		let east = translationPoint([Number(point[0]), Number(point[1])], [1, 0], 10000).longitude;
		let north = translationPoint([Number(point[0]), Number(point[1])], [0, 1], 10000).latitude;
		let south = translationPoint([Number(point[0]), Number(point[1])], [0, -1], 10000).latitude;
		let west = translationPoint([Number(point[0]), Number(point[1])], [-1, 0], 10000).longitude;
		let positions = Cesium.Cartesian3.fromRadiansArray([east, north, east, south, west, south, west, north, east, north]);

		this.createTarget(position, positions, 10000 * Math.pow(2, 0.5));
		return [
			{
				longitude: east * constant,
				latitude: north * constant,
				height: 0,
			},
			{
				longitude: east * constant,
				latitude: south * constant,
				height: 0,
			},
			{
				longitude: west * constant,
				latitude: south * constant,
				height: 0,
			},
			{
				longitude: west * constant,
				latitude: north * constant,
				height: 0,
			},
		];
		// return `POLYGON((${east*constant} ${north*constant},${east*constant} ${south*constant},${west*constant} ${south*constant},${west*constant} ${north*constant},${east*constant} ${north*constant}))`
	},

	/**
	 * 将点目标外扩为矩形
	 * @param {Array}       point       目标点:格式[lon, lat]
	 * @param {Number}      distance    外扩距离:单位（公里）
	 * @returns {Array}     positions   结果数组：[east, north, east, south, west, south, west, north]
	 */
	pointExtend(point, distance) {
		if (!point || !Array.isArray(point) || point.length !== 2) return;
		try {
			let east = translationPoint([Number(point[0]), Number(point[1])], [1, 0], distance * 1000).longitude * constant;
			let north = translationPoint([Number(point[0]), Number(point[1])], [0, 1], distance * 1000).latitude * constant;
			let south = translationPoint([Number(point[0]), Number(point[1])], [0, -1], distance * 1000).latitude * constant;
			let west = translationPoint([Number(point[0]), Number(point[1])], [-1, 0], distance * 1000).longitude * constant;
			return [east, north, east, south, west, south, west, north];
		} catch (e) {
			return false;
		}
	},
	/**
	 * 绘制目标区域
	 * @param {Object}      position    目标区域中心点
	 * @param {Array}       positions   目标区域点数组
	 * @param {Number}      radius      包围球半径
	 * @param {String}      img         图片路径
	 * @param {Function}    leftClick   点击回调
	 */
	createTarget(position, positions, radius, img = imgEnum.place, leftClick) {
		this.removeMultiTarget();
		viewer.entities.removeById('target');
		viewer.entities.add({
			id: 'target',
			position: position,
			billboard: {
				image: img,
				horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
				verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
				distanceDisplayCondition: new Cesium.DistanceDisplayCondition(radius * 300),
			},
			polyline: {
				positions: positions,
				arcType: Cesium.ArcType.RHUMB,
				width: 3,
				material: Cesium.Color.fromCssColorString('rgba(253, 128, 69, 1.0)'),
				clampToGround: true,
				classificationType: Cesium.ClassificationType.TERRAIN,
				distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, radius * 300),
			},
			leftClick:
				leftClick ||
				function (entity) {
					viewer.zoomTo(entity, new Cesium.HeadingPitchRange(0, -Math.PI / 2, radius * 10));
				},
		});
	},
	/**
	 * 创建多个点目标区域
	 * @param {Object}   item   点目标
	 * @param {String}   item.id    目标id
	 * @param {Number}   item.lon   经度坐标
	 * @param {Number}   item.lat   纬度坐标
	 * @param {String}   item.type  目标类型: new || public || private
	 */
	createMultiTarget(item) {
		viewer.entities.add({
			id: item.id,
			position: Cesium.Cartesian3.fromDegrees(item.lon, item.lat),
			billboard: {
				image: imgEnum[item.type],
				width: 40,
				height: 40,
				horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
				verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
			},
		});
		dataJson.multiTargetId.push(item.id);
	},
	/**
	 * 获取多点目标wkt字符串
	 */
	getMultiTargetWKTString() {
		let str = 'MULTIPOINT(';
		let entity = null;
		let position = null;
		dataJson.multiTargetId.forEach(id => {
			entity = viewer.entities.getById(id);
			position = Cesium.C_carToDegrees(entity.position);
			str += `${position.lon} ${position.lat},`;
		});
		return str.substring(0, str.length - 1) + ')';
	},
	/**
	 * 清除多点目标
	 * @param {String} id 需要删除的id，若为空则全部清除
	 */
	removeMultiTarget(id) {
		if (id) {
			viewer.entities.removeById(id);
		} else {
			dataJson.multiTargetId.forEach(id => {
				viewer.entities.removeById(id);
			});
			dataJson.multiTargetId.length = 0;
		}
	},
	/**
	 * 控制目标区域显示
	 * @param {Object}  flag    是否显示
	 */
	controlTargetShow(flag) {
		let entity = viewer.entities.getById('target');
		entity && (entity.show = flag);
		dataJson.administrativeDivisions && (dataJson.administrativeDivisions.show = flag);
	},

	/**
	 * 重绘目标图形
	 * @param {Object}  options     详细参数如下
	 * @param {Array}   options.center      圆心坐标，格式：[lon, lat]
	 * @param {Number}  options.radius      圆半径
	 * @param {Array}   options.positions   坐标数组, 格式：[lon, lat, lon, lat ......]
	 */
	redrawTarget(options = {}) {
		let checkPositions = options.positions && options.positions.length > 0 && options.positions.length % 2 === 0;
		let checkCircle = options.center && options.center.length === 2 && options.radius && options.radius > 0;
		if (!checkPositions && !checkCircle) {
			return false;
		}
		let positions = null;
		try {
			if (checkPositions) {
				positions = Cesium.Cartesian3.fromDegreesArray(options.positions);
				if (positions.length === 1) {
					let entity = viewer.entities.getById('target');
					if (entity && entity.polyline.positions.length === 0) {
						entity.position = positions[0];
					} else {
						this.createTarget(positions[0], [], 0, imgEnum.defaultImg, () => {});
					}
					return this.carToWktString(positions);
				}
				let boundingSphere = Cesium.BoundingSphere.fromPoints(positions);
				updateTargetPositions(positions, boundingSphere.center, boundingSphere.radius);
				return this.carToWktString(positions);
			}
			if (checkCircle) {
				let center = null;
				center = Cesium.Cartesian3.fromDegrees(options.center[0], options.center[1]);
				let geometry = Cesium.CircleOutlineGeometry.createGeometry(
					new Cesium.CircleOutlineGeometry({
						center: center,
						radius: options.radius,
					})
				);
				positions = Cesium.Cartesian3.unpackArray(geometry.attributes.position.values);
				updateTargetPositions(positions, center, options.radius);
				return this.carToWktString(positions);
			}
		} catch (err) {
			console.error(err);
			return false;
		}
		return false;
	},

	/**
	 * 显示当前页数据范围
	 * @param {Array}  items    当前页数据
	 */
	createCurrentDataArea(items = []) {
		let entity = null;

		for (let i = 0; i < dataJson.currentPageData.length; ++i) {
			viewer.entities.removeById(dataJson.currentPageData[i]);
		}
		dataJson.currentPageData.length = 0;

		for (let i = 0; i < items.length; ++i) {
			let id = items[i].id;
			entity = viewer.entities.getById(id);
			if (entity || !items[i].imageboundary) break;
			let positions = wktToCartesian3(items[i].imageboundary);
			viewer.entities.add({
				id: id,
				polyline: {
					positions: positions,
					arcType: Cesium.ArcType.RHUMB,
					width: 3,
					material: Cesium.Color.YELLOW,
					clampToGround: true,
					classificationType: Cesium.ClassificationType.TERRAIN,
					zIndex: 5,
				},
			});
			dataJson.currentPageData.push(id);
		}
	},
	/**
	 * 显示当前页数据范围
	 * @param {Array}  items     当前页数据
	 */
	createWKTArea(items) {
		let entity = null;

		for (let i = 0; i < dataJson.currentPageData.length; ++i) {
			viewer.entities.removeById(dataJson.currentPageData[i]);
		}
		dataJson.currentPageData.length = 0;

		for (let i = 0; i < items.length; ++i) {
			let id = items[i].gid;
			entity = viewer.entities.getById(id);
			if (entity) return;
			let positions = items[i].geom.replace('MULTIPOLYGON (((', '').replace(')))', '').split(', ');
			for (let i = 0; i < positions.length; ++i) {
				let p = positions[i].split(' ');
				positions[i] = Cesium.Cartesian3.fromDegrees(Number(p[0]), Number(p[1]));
			}
			viewer.entities.add({
				id: id,
				polyline: {
					positions: positions,
					width: 3,
					arcType: Cesium.ArcType.RHUMB,
					material: Cesium.Color.YELLOW,
					clampToGround: true,
					classificationType: Cesium.ClassificationType.TERRAIN,
					zIndex: 5,
				},
			});
			dataJson.currentPageData.push(id);
		}
	},
	/**
	 *  更改当前实体显示状态
	 * @param {Sting}   id      实体id
	 * @param {Boolean} flag    显示状态
	 */
	currentItem(id, flag) {
		let entity = viewer.entities.getById(id);
		if (entity) {
			entity.polyline.material = flag ? Cesium.Color.RED : Cesium.Color.YELLOW;
			entity.polyline.zIndex = flag ? 10 : 5;
		}
	},
	/**
	 * 相机定位至实体
	 * @param {String}  id      目标id，要求目标为包含线类型的实体
	 * @param {Number}  scale   相机移动距离半数，默认为10
	 */
	flyToTarget(id, scale = 10) {
		let entity = viewer.entities.getById(id);
		let positions = entity.polyline.positions._value;
		this.flyToBoundingSphere(positions, scale);
	},
	/**
	 * 相机对位
	 * @param {Array}   positions   目标的坐标数组
	 * @param {Number}  scale       相机移动距离半数，默认为10
	 */
	flyToBoundingSphere(positions, scale = 10) {
		if (!positions || positions.length < 1) return;
		let boundingSphere = Cesium.BoundingSphere.fromPoints(positions);
		viewer.camera.flyToBoundingSphere(boundingSphere, {
			offset: new Cesium.HeadingPitchRange(0, -Math.PI / 2, boundingSphere.radius * scale),
		});
	},
	/**
	 * 相机对位
	 * @param {Object}  position    目标点: {lon: XXX, lat: XXX, height: XXX}
	 * @param {Object}  orientation  相机姿态参数
	 */
	flyToPosition(position, orientation) {
		if (!position) return;
		viewer.camera.flyTo({
			destination: Cesium.Cartesian3.fromDegrees(position.lon, position.lat, position.height),
			orientation: orientation,
		});
	},
	/**
	 * 清空所有已选择的影像
	 */
	clearAllSelectImage(layer, type) {
		let keys = [];
		dataSources[layer].entities.values.forEach(entity => {
			entity.type === type && keys.push(entity.id);
		});
		keys.forEach(id => {
			dataSources[layer].entities.removeById(id);
			dataJson.checkedMap.splice(dataJson.checkedMap.indexOf(id), 1);
		});
	},
	/**
	 * 行政区划绘制
	 * @param {Object} data  geojson格式的矢量数据
	 */
	createAdministrativeDivisions(data) {
		this.clearToolArea();
		if (!data) return;
		let geo = data;
		let entity = null;
		let color = Cesium.Color.fromCssColorString('rgba(253, 128, 69, 1.0)');
		Cesium.GeoJsonDataSource.load(geo).then(dataSource => {
			for (let i = 0; i < dataSource.entities.values.length; ++i) {
				entity = dataSource.entities.values[i];
				if (!entity.polygon) continue;
				entity.polygon = new Cesium.PolygonGraphics({
					arcType: Cesium.ArcType.RHUMB,
					hierarchy: entity.polygon.hierarchy,
					outline: false,
					material: color.withAlpha(0.2),
					classificationType: Cesium.ClassificationType.TERRAIN,
				});
				entity.polyline = new Cesium.PolylineGraphics({
					positions: [...entity.polygon.hierarchy._value.positions, entity.polygon.hierarchy._value.positions[0]],
					width: 3,
					material: color,
					clampToGround: true,
					classificationType: Cesium.ClassificationType.TERRAIN,
					zIndex: 0,
				});
				let holes = entity.polygon.hierarchy._value.holes;
				for (let j = 0; j < holes.length; ++j) {
					dataSource.entities.add({
						polyline: {
							positions: [...holes[j].positions, holes[j].positions[0]],
							width: 3,
							clampToGround: true,
							material: color,
							classificationType: Cesium.ClassificationType.TERRAIN,
							zIndex: 0,
						},
					});
				}
			}
			viewer.dataSources.add(dataSource);
			viewer.zoomTo(dataSource, new Cesium.HeadingPitchRange(0, -Math.PI / 2, 0));
			dataJson.administrativeDivisions = dataSource;
		});
	},
	/**
	 * 清除目标区域
	 */
	clearToolArea() {
		this.removeMultiTarget();
		// 清空绘制区域
		viewer.entities.removeById('target');
		// 清空矢量区域
		viewer.dataSources.remove(dataJson.administrativeDivisions);
		dataJson.administrativeDivisions = null;
	},
	clearAreaAddCurrentPage() {
		viewer.dataSources.remove(dataJson.dataArea);
		dataJson.dataArea = null;
		for (let i = 0; i < dataJson.currentPageData.length; ++i) {
			viewer.entities.removeById(dataJson.currentPageData[i]);
		}
		dataJson.currentPageData.length = 0;
	},
	/**
	 * 将wkt格式数据转化为经纬度
	 * @param {String} wktString wkt格式点坐标
	 */
	wktToDegrees(wktString) {
		let str = wktString.replace(/[POLYGON()]/g, '');
		str = wktString.replace(/,/g, ' ');
		return str
			.split(' ')
			.map(parseFloat)
			.filter(item => item || item === 0);
	},
	/**
	 * 将wkt格式数据转化为世界坐标
	 * @param {String} wktString wkt格式点坐标
	 */
	wktToCartesian3(wktString) {
		return Cesium.Cartesian3.fromDegreesArray(wktToDegrees(wktString));
	},
	/**
	 * 控制实体显示隐藏
	 * @param {Array}   layer   需要操作的实体
	 * @param {Boolean} flag    显示/隐藏
	 */
	controlLayer(layer, flag) {
		dataSources[layer].show = flag;
	},
	/**
	 *
	 * @param {Array}   layer   需要操作的实体
	 * @param {String}  type    需要显示的实体类型
	 */
	controlEntity(layer, type) {
		dataSources[layer].entities.values.forEach(entity => {
			entity.show = entity.type === type;
		});
	},
	/**
	 * 控制模型添加
	 * @param {Boolean} flag    是否添加
	 * @param {String}  url     模型路径
	 */
	addModel(flag, url) {
		viewer.entities.removeById('tree_model');
		if (flag) {
			if (!/\.(glb|gltf)$/.test(url)) {
				throw new Error('本系统暂时只支持glb和gltf格式的模型文件，请确认模型格式正确');
			}
			let position = viewer.camera.pickEllipsoid({
				x: viewer.container.clientWidth / 2,
				y: viewer.container.clientHeight / 2,
			});
			let cartographic = Cesium.Cartographic.fromCartesian(position);
			cartographic.height += 1000;
			position = Cesium.Cartographic.toCartesian(cartographic);
			let entity = viewer.entities.add({
				id: 'tree_model',
				position: position,
				model: {
					uri: url,
					minimumPixelSize: 256,
					maximumScale: 20000,
				},
			});
			viewer.zoomTo(entity);
		}
	},
	/**
	 * 控制倾斜摄影模型添加
	 * @param {Boolean} flag    是否添加
	 * @param {String}  url     倾斜摄影模型路径
	 */
	addDSM(flag, url) {
		viewer.scene.primitives.remove(dsm);
		dsm = null;
		if (flag) {
			url = /tileset\.json$/.test(url) ? url : url + '/tileset.json';
			let tileset = new Cesium.Cesium3DTileset({
				url: url,
			});
			tileset.readyPromise.then(tileset => {
				viewer.scene.primitives.add(tileset);
				viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0.0, -0.5, tileset.boundingSphere.radius * 2.0));
				dsm = tileset;
			});
		}
	},
	/**
	 * 世界坐标转wkt坐标字符串
	 * @param {Array} positions 世界坐标数组
	 */
	carToWktString(positions) {
		if (!(positions || Cesium.isArray(positions) || positions.length < 1)) return;
		let degrees = positions.map(item => {
			return Cesium.C_carToDegrees(item);
		});
		return this.degreesToWKTString(degrees);
	},
	/**
	 * 将经纬度转为wkt字符串
	 * @param {Array} degrees   经纬度数组，格式：[{longitude: xxx, latitude:xxx}, {longitude: xxx, latitude:xxx}, ......]
	 */
	degreesToWKTString(degrees) {
		if (!(degrees || Cesium.isArray(degrees) || degrees.length < 1)) return;
		if (degrees.length === 1) {
			return `POINT(${degrees[0].longitude} ${degrees[0].latitude})`;
		}
		let bool = false;
		for (let i = 1; i < degrees.length; ++i) {
			if (Math.abs(degrees[i].longitude - degrees[i - 1].longitude) > 180) {
				bool = true;
				break;
			}
		}
		if (bool) {
			let ps1 = '';
			let ps2 = '';
			let ps1Arr = [];
			let ps2Arr = [];
			for (let i = 0; i < degrees.length; ++i) {
				if (degrees[i].longitude > 0) {
					ps1 += `${degrees[i].longitude} ${degrees[i].latitude},`;
					ps2 += `${degrees[i].longitude - 360} ${degrees[i].latitude},`;
					ps1Arr.push(degrees[i]);
					ps2Arr.push({
						longitude: degrees[i].longitude - 360,
						latitude: degrees[i].latitude,
					});
				} else {
					ps1Arr.push({
						longitude: degrees[i].longitude + 360,
						latitude: degrees[i].latitude,
					});
					ps2Arr.push(degrees[i]);
					ps1 += `${degrees[i].longitude + 360} ${degrees[i].latitude},`;
					ps2 += `${degrees[i].longitude} ${degrees[i].latitude},`;
				}
			}
			if (degrees[0].longitude > 0) {
				ps1 += `${degrees[0].longitude} ${degrees[0].latitude}`;
				ps2 += `${degrees[0].longitude - 360} ${degrees[0].latitude}`;
			} else {
				ps1 += `${degrees[0].longitude + 360} ${degrees[0].latitude}`;
				ps2 += `${degrees[0].longitude} ${degrees[0].latitude}`;
			}
			let multiPolygon = `MultiPolygon(((${ps1})),((${ps2})))`;

			return multiPolygon;
		}

		let polygon = 'POLYGON((';
		for (let i = 0; i < degrees.length; i++) {
			polygon += `${degrees[i].longitude} ${degrees[i].latitude},`;
		}
		polygon += `${degrees[0].longitude} ${degrees[0].latitude}))`;

		return polygon;
	},

	degreesToBothWKTString(degrees) {
		if (!(degrees || Cesium.isArray(degrees) || degrees.length < 1)) return;
		if (degrees.length === 1) {
			return {
				wkt: `POINT(${degrees[0].longitude} ${degrees[0].latitude}) `,
				inverseWkt: `POINT(${degrees[0].latitude} ${degrees[0].longitude}) `,
			};
		}
		let bool = false;
		for (let i = 1; i < degrees.length; ++i) {
			if (Math.abs(degrees[i].longitude - degrees[i - 1].longitude) > 180) {
				bool = true;
				break;
			}
		}
		if (bool) {
			let ps1 = '';
			let ps2 = '';
			let ps3 = '';
			let ps4 = '';
			let ps1Arr = [];
			let ps2Arr = [];
			for (let i = 0; i < degrees.length; ++i) {
				if (degrees[i].longitude > 0) {
					ps1 += `${degrees[i].longitude} ${degrees[i].latitude}, `;
					ps3 += `${degrees[i].latitude} ${degrees[i].longitude}, `;
					ps2 += `${degrees[i].longitude - 360} ${degrees[i].latitude}, `;
					ps4 += `${degrees[i].latitude} ${degrees[i].longitude - 360}, `;
					ps1Arr.push(degrees[i]);
					ps2Arr.push({
						longitude: degrees[i].longitude - 360,
						latitude: degrees[i].latitude,
					});
				} else {
					ps1Arr.push({
						longitude: degrees[i].longitude + 360,
						latitude: degrees[i].latitude,
					});
					ps2Arr.push(degrees[i]);
					ps1 += `${degrees[i].longitude + 360} ${degrees[i].latitude}, `;
					ps3 += `${degrees[i].latitude} ${degrees[i].longitude + 360}, `;
					ps2 += `${degrees[i].longitude} ${degrees[i].latitude}, `;
					ps4 += `${degrees[i].latitude} ${degrees[i].longitude}, `;
				}
			}
			if (degrees[0].longitude > 0) {
				ps1 += `${degrees[0].longitude} ${degrees[0].latitude}`;
				ps3 += `${degrees[0].latitude} ${degrees[0].longitude}`;
				ps2 += `${degrees[0].longitude - 360} ${degrees[0].latitude}`;
				ps4 += `${degrees[0].latitude} ${degrees[0].longitude - 360}`;
			} else {
				ps1 += `${degrees[0].longitude + 360} ${degrees[0].latitude}`;
				ps3 += `${degrees[0].latitude} ${degrees[0].longitude + 360}`;
				ps2 += `${degrees[0].longitude} ${degrees[0].latitude}`;
				ps4 += `${degrees[0].latitude} ${degrees[0].longitude}`;
			}
			return {
				wkt: `MultiPolygon((( ${ps1} )), (( ${ps2} )))`,
				inverseWkt: `MultiPolygon((( ${ps3} )), (( ${ps4} )))`,
			};
		}

		let polygon = 'POLYGON(( ';
		let inversePolygon = 'POLYGON(( ';
		for (let i = 0; i < degrees.length; i++) {
			polygon += `${degrees[i].longitude} ${degrees[i].latitude}, `;
			inversePolygon += `${degrees[i].latitude} ${degrees[i].longitude}, `;
		}
		polygon += `${degrees[0].longitude} ${degrees[0].latitude} ))`;
		inversePolygon += `${degrees[0].latitude} ${degrees[0].longitude} ))`;

		return {
			wkt: polygon,
			inverseWkt: inversePolygon,
		};
	},
	/**
	 * 解析各种格式的坐标，将其解析为坐标数组的形式
	 * @param {String} target 坐标字符串
	 */
	formatConversion(target) {
		if (typeof target === 'string') {
			target = target
				.replace(/(\s+)?[°度]/g, '°')
				.replace(/(\s+)?['分]/g, "'")
				.replace(/(\s+)?["秒]/g, '"');
			let strPositionsArr = target.split(/[，,；;(\s+)]/g).filter(item => item && item.trim());
			let positions = [];
			strPositionsArr.forEach(item => {
				coordinateHandle(item, positions);
			});
			return positions;
		} else if (typeof target === 'number') {
			return target;
		} else {
			return false;
		}
	},
	/**
	 *
	 */
	tsReplay(url, tracks) {
		if (!viewer.dataSources.contains(dataSources.historyPathMarker)) {
			viewer.dataSources.add(dataSources.historyPathMarker);
		}
		let entities = dataSources.historyPathMarker.entities;
		entities.removeAll();
		if (tracks.length === 0) return;
		let cartesian3Arr = [];
		let sampledPosition = new Cesium.SampledPositionProperty();
		tracks.forEach(item => {
			let p = Cesium.Cartesian3.fromDegrees(item.lon, item.lat);
			cartesian3Arr.push(p);
			let time = Cesium.JulianDate.fromDate(new Date(item.time * 1000));
			sampledPosition.addSample(time, p);
			entities.add({
				position: p,
				point: {
					pixelSize: 6,
					color: Cesium.Color.YELLOW,
					outlineWidth: 0,
					heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
				},
			});
		});
		// this.flyToBoundingSphere(cartesian3Arr, 5);
		entities.add({
			polyline: {
				positions: cartesian3Arr,
				width: 2,
				material: Cesium.Color.WHITE,
				clampToGround: true,
			},
		});
		entities.add({
			availability: new Cesium.TimeIntervalCollection([
				new Cesium.TimeInterval({
					start: Cesium.JulianDate.fromDate(new Date(tracks[0].time * 1000)),
					stop: Cesium.JulianDate.fromDate(new Date(tracks[tracks.length - 1].time * 1000)),
				}),
			]),
			position: sampledPosition,
			orientation: new Cesium.VelocityOrientationProperty(sampledPosition),
			model: {
				uri: url,
				// minimumPixelSize: 0.001,
				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
				scale: 0.03,
			},
		});
	},
	stopTsPlay() {
		dataSources.historyPathMarker.entities.removeAll();
	},
	createWarningArea(id, positions, show) {
		if (viewer.entities.getById(id)) return;
		viewer.entities.add({
			id: id,
			show: show,
			polyline: {
				positions: positions,
				width: 3,
				material: Cesium.Color.fromCssColorString('rgb(253, 128, 69)'),
				clampToGround: true,
			},
		});
	},
	updateWarningArea(id, positions) {
		console.log(id, positions);
	},
	/**
	 * 创建数据源标识
	 * @param {Object} item 数据源信息
	 */
	createDataSourcePoint(item) {
		if (item.type === 'fj') {
			this.createClusteringTarget(item.fcbm, item);
		} else if (item.type === 'radar') {
			viewer.entities.add({
				id: Cesium.createGuid(),
				position: Cesium.Cartesian3.fromDegrees(item.lon, item.lat),
				billboard: {
					image: imgEnum[item.type], // TODO
					width: 24,
					height: 24,
					verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
				},
				type: 'radar',
				item: item,
			});
			// if (item.radius) {
			//     this.createEnvelope(item);
			// }
		} else {
			let position = item.type === '760' ? Cesium.Cartesian3.fromDegrees(coordinateHandle(item.lon), coordinateHandle(item.lat)) : Cesium.Cartesian3.fromDegrees(item.lon, item.lat);
			viewer.entities.add({
				id: Cesium.createGuid(),
				position: position,
				billboard: {
					image: imgEnum[item.type], // TODO
					width: 24,
					height: 24,
					verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
				},
				type: 'dataSourcePoint',
				info: JSON.stringify(item),
			});
		}
	},
	/**
	 * 创建风场聚合点
	 * @param {String} name 风场名称
	 * @param {Object} data 风场数据
	 */
	createClusteringTarget(name, data) {
		if (!dataSources[name]) {
			let dataSource = new Cesium.CustomDataSource(name);
			ClusteringDataSources[name] = dataSource;
			viewer.dataSources.add(dataSource);
			dataSource.clustering.enabled = true;
			dataSource.clustering.pixelRange = 15;
			dataSource.clustering.minimumClusterSize = 2;
			dataSource.clustering.clusterEvent.addEventListener((clusteredEntities, cluster) => {
				cluster.label.font = '30px';
				cluster.label.fillColor = Cesium.Color.BLACK;
				cluster.label.pixelOffset = new Cesium.Cartesian2(0, -30);
				cluster.label.horizontalOrigin = Cesium.HorizontalOrigin.CENTER;
				cluster.label.show = true;
				cluster.billboard.show = true;
				cluster.billboard.image = imgEnum['fc'];
				cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
				cluster.billboard.width = 30;
				cluster.billboard.height = 30;
				cluster.billboard.type = 'clusteringDataSourcePoint';
				let name = JSON.parse(cluster.label.id[0].info).fcbm;
				cluster.billboard.info = JSON.stringify({ type: 'fj', fcbm: name });
			});
		}
		ClusteringDataSources[name].entities.add({
			id: data.fcbm + data.fjbm,
			position: Cesium.Cartesian3.fromDegrees(data.lon, data.lat),
			billboard: {
				image: imgEnum['fj'],
				width: 30,
				height: 30,
				verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
			},
			type: 'dataSourcePoint',
			info: JSON.stringify(data),
		});
	},
	clearClusteringTarget() {
		Object.keys(ClusteringDataSources).forEach(key => {
			ClusteringDataSources[key].entities.removeAll();
		});
	},
	/**
	 * 查看风机
	 * @param {Object} item 风机参数
	 * @param {Boolean} flag 是否定位至风机
	 */
	lookFJ(item, flag) {
		this.clearFJSelect && this.clearFJSelect();
		let entity = dataSources[item.fcbm].entities.getById(item.fcbm + item.fjbm);
		if (entity) {
			let coor = Cesium.C_carToDegrees(entity.position._value);
			entity.billboard.image = imgEnum['fjR'];
			if (flag) {
				viewer.camera.flyTo({
					destination: Cesium.Cartesian3.fromDegrees(coor.lon, coor.lat, 5000),
				});
			}
			this.clearFJSelect = () => {
				entity.billboard.image = imgEnum['fj'];
				entity = null;
				this.clearFJSelect = null;
			};
		} else {
			debugger;
		}
	},
	/**
	 * 创建扫描波束
	 * @param {Cartesian3}  center  中心点
	 * @param {Number}      radii   半径
	 */
	createEnvelope(item) {
		if (!viewer.scene.primitives.contains(dataSources.monitorScenePrimitives)) {
			viewer.scene.primitives.add(dataSources.monitorScenePrimitives);
		}
		let center = Cesium.Cartesian3.fromDegrees(item.lon, item.lat);
		let radii = item.radius;
		let color = Cesium.Color.fromCssColorString('rgba(0, 204, 0, 0.2)');
		let startAngle = 0;
		let endAngle = item.range;
		let positions = baseFunc.getSpherePosition(88, 90, startAngle, endAngle);
		let indices = baseFunc.getSphereIndices(1, 0, true, true);
		let lineIndices = baseFunc.getSphereLineIndices(1, 3, false, false);
		let length = positions.length / 3 - 1;
		positions[2] = 0;
		positions[positions.length - 1] = 0;
		lineIndices.push(0, 1, 0, 65, 0, length - 1, 0, length - 65);
		let modelMatrix = Cesium.Matrix4.multiplyByUniformScale(Cesium.Transforms.eastNorthUpToFixedFrame(center), radii, new Cesium.Matrix4());
		let geometryInstance = baseFunc.getGeometryInstance(positions, indices, 4, modelMatrix, color);
		let outlineGeometryInstance = baseFunc.getGeometryInstance(positions, lineIndices, 1, modelMatrix, Cesium.Color.fromCssColorString('rgba(0, 204, 0, 1.0)'));
		let inverseModelMatrix = Cesium.Matrix4.inverse(modelMatrix, new Cesium.Matrix4());
		let primitive = dataSources.monitorScenePrimitives.add(baseFunc.getPrimitive(geometryInstance));
		primitive.type = 'dataSourcePoint';
		primitive.sourceType = item.type;
		primitive.source = item.source;
		primitive.name = item.name;

		let linePrimitive = dataSources.monitorScenePrimitives.add(baseFunc.getPrimitive(outlineGeometryInstance));

		// 扫描波束
		let beamStartAngle = 0;
		let beamEndAngle = 1;
		let beamPositions = baseFunc.getSpherePosition(88, 90, beamStartAngle, beamEndAngle);
		let beamIndices = baseFunc.getSphereIndices(1, 0, true, true);
		beamPositions[2] = 0;
		beamPositions[positions.length - 1] = 0;
		for (let i = 0; i < 32; ++i) {
			beamIndices.push(0, i * 65 + 1, (i + 1) * 65 + 1);
			beamIndices.push(0, (i + 1) * 65, (i + 2) * 65);
		}

		let colors = [0, 0, 0, 0];
		for (let i = 1; i < beamPositions.length / 3 - 1; ++i) {
			colors.push(255, 255, 0, 150);
		}
		colors.push(0, 0, 0, 0);
		let beamGeometryInstance = baseFunc.getGeometryInstanceWithColor(beamPositions, beamIndices, 4, modelMatrix, colors);
		let beamPrimitive = dataSources.monitorScenePrimitives.add(baseFunc.getPrimitive(beamGeometryInstance));
		let spinAngle = 0;
		let spinStep = 2;
		let angle = item.rotation;

		Cesium.Matrix4.multiplyByUniformScale(Cesium.Transforms.eastNorthUpToFixedFrame(center), radii, beamPrimitive.modelMatrix);

		let quaternion = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, angle * degreesToRadian);
		// 包络
		let m3 = Cesium.Matrix3.fromQuaternion(quaternion);
		Cesium.Matrix4.multiplyByUniformScale(Cesium.Matrix4.multiplyByMatrix3(Cesium.Transforms.eastNorthUpToFixedFrame(center), m3, new Cesium.Matrix4()), radii, primitive.modelMatrix);

		Cesium.Matrix4.multiply(primitive.modelMatrix, inverseModelMatrix, primitive.modelMatrix);
		Cesium.Matrix4.multiply(beamPrimitive.modelMatrix, inverseModelMatrix, beamPrimitive.modelMatrix);

		linePrimitive.modelMatrix = primitive.modelMatrix;

		let listener = viewer.scene.preRender.addEventListener((scene, currentTime) => {
			if (spinAngle === endAngle - 2) {
				spinStep = -2;
			}
			if (spinAngle === 0) {
				spinStep = 2;
			}
			spinAngle += spinStep;
			let beamQuaternion = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, (angle + spinAngle) * degreesToRadian);
			// 波束
			Cesium.Matrix4.multiplyByUniformScale(
				Cesium.Matrix4.multiplyByMatrix3(Cesium.Transforms.eastNorthUpToFixedFrame(center), Cesium.Matrix3.fromQuaternion(beamQuaternion), new Cesium.Matrix4()),
				radii,
				beamPrimitive.modelMatrix
			);

			Cesium.Matrix4.multiply(beamPrimitive.modelMatrix, inverseModelMatrix, beamPrimitive.modelMatrix);
		});

		listenerArr.push(listener);
	},
	/**
	 * 清除波束
	 */
	clearEnvelope() {
		listenerArr.forEach(item => {
			item();
		});
		dataSources.monitorScenePrimitives.removeAll();
	},
};
export default func;
